import axios, { AxiosError, AxiosResponse } from "axios";
import type {
    AxiosInstance,
    InternalAxiosRequestConfig,
    AxiosRequestConfig,
} from "axios";
import { ElMessage } from "element-plus";
import { getMessageInfo } from "./status";

// 定义接口类型《后端返回的最外层数据类型》
interface BaseResponse<T = any> {
    code: number | string;
    message: string;
    data: T;
}
const service: AxiosInstance = axios.create({
    // baseURL: '/',
    // 这样我们就可以在环境变量中改变 axios 的 baseURL
    baseURL: import.meta.env.VITE_APP_DEV_USE_MOCK
        ? import.meta.env.VITE_APP_MOCK_BASEURL
        : import.meta.env.VITE_APP_API_BASEURL,
    timeout: 10000,
});

// axios 实例拦截请求
service.interceptors.request.use(
    (config: InternalAxiosRequestConfig) => {
        return config;
    },
    (err: AxiosError) => {
        return Promise.reject(err);
    },
);

// axios 实例拦截响应
service.interceptors.response.use(
    (response: AxiosResponse) => {
        if (response.status === 200) {
            // const data = response.data;
            return response;
        }
        ElMessage({
            message: getMessageInfo(response.status),
            type: "error",
        });
        return response;
    },
    (err: AxiosError) => {
        return Promise.reject(err);
    },
);
// 此处相当于二次响应拦截
// 为响应数据进行定制化处理
const requestInstance = <T = any>(config: AxiosRequestConfig): Promise<T> => {
    const conf = config;
    return new Promise((resolve, reject) => {
        service
            .request<any, AxiosResponse<BaseResponse>>(conf)
            .then((res: AxiosResponse<BaseResponse>) => {
                const data = res.data; // 如果data.code为错误代码返回message信息
                if (data.code != 0) {
                    ElMessage({
                        message: data.message,
                        type: "error",
                    });
                    reject(data.message);
                } else {
                    ElMessage({
                        message: data.message,
                        type: "success",
                    }); // 此处返回data信息 也就是 api 中配置好的 Response类型
                    resolve(data as T);
                }
            });
    });
};

// 在最后使用封装过的axios导出不同的请求方式
export function get<T = any, U = any>(
    config: AxiosRequestConfig,
    url: string,
    parms?: U,
): Promise<T> {
    return requestInstance({ ...config, url, method: "GET", params: parms });
}
export function post<T = any, U = any>(
    config: AxiosRequestConfig,
    url: string,
    data: U,
): Promise<T> {
    return requestInstance({ ...config, url, method: "POST", data: data });
}
export function put<T = any, U = any>(
    config: AxiosRequestConfig,
    url: string,
    parms?: U,
): Promise<T> {
    return requestInstance({ ...config, url, method: "PUT", params: parms });
}
export function del<T = any, U = any>(
    config: AxiosRequestConfig,
    url: string,
    data: U,
): Promise<T> {
    return requestInstance({ ...config, url, method: "DELETE", data: data });
}

// 一般的后端返回的数据结构
// {
//     'code': 1,
//     'message': '成功',
//     'data': {
//         'id': 1,
//         'name': '张三',
//         'age': 18,
//         'sex': 1,
//         'address': '北京市',
//         'createTime': '2021-08-30 15:49:16',
//         'updateTime': '2021-08-30 15:49:16',
//         'deleteTime': null,
//         'createBy': 1,
//         'updateBy': 1,
//     }

// }
